#include "AutoLock.h"
#include <windows.h>
#include <assert.h>
#include <boost/lexical_cast.hpp>

namespace yet {
ILock::~ILock() {
}

ProcessLock::ProcessLock(wstring key) {
	event = CreateEvent(0, FALSE, TRUE, key.c_str());
	assert(event);
}

ProcessLock::~ProcessLock(void) {
	SetEvent(event);
	CloseHandle(event);
}

bool ProcessLock::lock(DWORD timeout) {
	DWORD n = WaitForSingleObject(event, timeout);
	switch (n) {
	case WAIT_FAILED : //fallthrough
	case WAIT_ABANDONED: //fallthrough
	case WAIT_TIMEOUT:
		break;
	case WAIT_OBJECT_0:
		return true;
		break;
	}
	return false;
}
void ProcessLock::unLock() {
	SetEvent(event);
}

ThreadLock::ThreadLock() {
	::InitializeCriticalSection(&section);
}

ThreadLock::~ThreadLock() {
	::DeleteCriticalSection(&section);
}

bool ThreadLock::lock(DWORD timeout) {
	::EnterCriticalSection(&section);
	return true;
}
void ThreadLock::unLock() {
	::LeaveCriticalSection(&section);
}
bool ThreadLock::tryLock() {
	return 0 != ::TryEnterCriticalSection(&section);
}

AutoLock::AutoLock(ILock& lockInstance, DWORD timeout) {
	lock = &lockInstance;
	lock->lock(timeout);
}
AutoLock::AutoLock(ILock* lockInstance, DWORD timeout) {
	lock = lockInstance;
	lock->lock(timeout);
}
AutoLock::~AutoLock() {
	if (lock) {
		lock->unLock();
	}
}

void AutoLock::unLock() {
	lock->unLock();
	lock = 0;
}
}
